package com.mdoya.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mdoya.domain.Dish;
import com.mdoya.domain.Setmeal;
import com.mdoya.domain.SetmealDish;
import com.mdoya.dto.SetmealDto;
import com.mdoya.exception.BusinessExceptiion;
import com.mdoya.mapper.SetmealMapper;
import com.mdoya.query.BaseQuery;
import com.mdoya.service.SetmealDishService;
import com.mdoya.service.SetmealService;
import com.mdoya.vo.SetmealVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.security.Key;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mdoya
 * @version 1.0
 * @description:
 */
@Scope("singleton")
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishService setmealDishService;

    /**
     * 根据分类id查询分类总数量
     *
     * @param categoryId
     * @return
     */
    @Cacheable(key = "#categoryId",cacheNames = "setmealCache")
    @Override
    public Integer selectCategoryById(Long categoryId) {
        LambdaQueryWrapper<Setmeal> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Setmeal::getCategoryId, categoryId);
        return setmealMapper.selectCount(wrapper);
    }

    /**
     * 新增套餐
     *
     * @param setmealDto
     * @return
     */
    @CacheEvict(key = "#setmealDto.categoryId+'_'+#setmealDto.status",cacheNames = "setmealCache")
    @Override
    public Integer insert(SetmealDto setmealDto) {
        int rows = setmealMapper.insert(setmealDto);

        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        if (setmealDishes != null && setmealDishes.size() > 0) {
            List<Integer> collect = setmealDishes.stream().map((item) -> {
                item.setSetmealId(setmealDto.getId());
                return setmealDishService.add(item);
            }).collect(Collectors.toList());
            return rows > 0 && collect.size() == setmealDishes.size() ? 1 : 0;
        }
        return rows;
    }

    /**
     * 套餐分页查询
     *
     * @param query
     * @return
     */
    @Override
    public IPage<SetmealVo> selectPage(BaseQuery query) {
        IPage<Setmeal> setmealPage = new Page<>(query.getPage(), query.getPageSize());
        LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealLambdaQueryWrapper.eq(query.getName() != null, Setmeal::getName, query.getName());
        setmealMapper.selectPage(setmealPage, setmealLambdaQueryWrapper);

        // 重装封装数据
        IPage<SetmealVo> setmealVoPage = new Page<>();
        setmealVoPage.setTotal(setmealPage.getTotal());
        List<SetmealVo> setmealVoList = setmealPage.getRecords().stream().map((item) -> {
            SetmealVo setmealVo = new SetmealVo();
            setmealVo.setCategoryName(item.getName());
            BeanUtils.copyProperties(item, setmealVo);
            List<SetmealDish> setmealDishList = setmealDishService.findSetmealIdByList(item.getId());
            setmealVo.setSetmealDishes(setmealDishList);
            return setmealVo;
        }).collect(Collectors.toList());
        setmealVoPage.setRecords(setmealVoList);

        return setmealVoPage;
    }

    /**
     * 更新套餐
     *
     * @param setmealDto
     * @return
     */
    @CacheEvict(cacheNames = "setmealCache",allEntries = true)
    @Override
    public Integer updateById(SetmealDto setmealDto) {
        int rows = setmealMapper.updateById(setmealDto);


        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        if (rows > 0 && setmealDishes != null) {
            // 删除口味
            setmealDishService.deleteSetmealDish(setmealDto.getId());

            // 更新口味
            List<Integer> addRows = setmealDishes.stream().map((item) -> {
                item.setSetmealId(setmealDto.getId());
                Integer row = setmealDishService.add(item);
                return row;
            }).collect(Collectors.toList());
            return rows > 0 && addRows.size() == setmealDishes.size() ? 1 : 0;
        }
        return rows;
    }

    /**
     * 删除套餐
     *
     * @param ids
     * @return
     */
    @CacheEvict(cacheNames = "setmealCache",allEntries = true)
    @Override
    public Integer delete(List<Long> ids) {
        // 校验是否正确销售
        LambdaQueryWrapper<Setmeal> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.eq(Setmeal::getStatus, 1);
        dishLambdaQueryWrapper.in(Setmeal::getId, ids);
        Integer count = setmealMapper.selectCount(dishLambdaQueryWrapper);
        if (count > 0) {
            throw new BusinessExceptiion(-1, "套餐正确销售，禁止删除");
        }
        // 删除套餐表
        int rows = setmealMapper.deleteBatchIds(ids);
        // 删除菜品表
        if (ids != null && ids.size() > 0) {
            List<Integer> rowList = ids.stream().map((item) -> {
                Integer row = setmealDishService.deleteSetmealDish(item);
                return row;
            }).collect(Collectors.toList());
            return rows > 0 && rowList.size() == ids.size() ? 1 : 0;
        }
        return rows;
    }

    /**
     * 修改状态
     *
     * @param ids
     * @param status
     * @return
     */
    @Override
    public Integer status(List<String> ids, String status) {
        Setmeal setmeal = new Setmeal();
        setmeal.setStatus(Integer.valueOf(status));
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId, ids);
        return setmealMapper.update(setmeal, queryWrapper);
    }

    /**
     * 前端套餐查询 cache缓存
     *
     * @param categoryId
     * @param status
     * @return
     */
    @Cacheable(key = "#categoryId+'_'+#status", cacheNames = "setmealCache")
    @Override
    public List<SetmealVo> list(Long categoryId, Integer status) {
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(categoryId != null, Setmeal::getCategoryId, categoryId);
        queryWrapper.eq(status != null, Setmeal::getStatus, status);
        queryWrapper.orderByAsc(Setmeal::getCreateTime);
        List<Setmeal> setmealList = setmealMapper.selectList(queryWrapper);
        List<SetmealVo> setmealVoList = setmealList.stream().map((item) -> {
            SetmealVo setmealVo = new SetmealVo();
            BeanUtils.copyProperties(item, setmealVo);
            List<SetmealDish> setmealDishList = setmealDishService.findSetmealIdByList(item.getId());
            setmealVo.setSetmealDishes(setmealDishList);
            return setmealVo;
        }).collect(Collectors.toList());

        return setmealVoList;
    }
}